-- Garden
-- Created by chengb Feb/4/2016
-- 花园格子

require "game/ui/form/bine/UIBineMain"
require "game/ui/form/bine/UIBineSelectTarget"

-- 内部函数声明
local createBine;
local createBineDisplay;
local handleBineAttribEffect;
local initEmptyGarden;
local isBineMpEnouth;

-- 初始化
function initGarden(self)
    self.item:removeAllChildren();

    self.item:setPositionY(10);

    -- 获取花园状态
    local pos = self.gridData:getPos();
    local state = BineM.getGardenState(pos);

    if state == GARDEN_EMPTY then
        if self.monsterNode.bineDisplay then
            -- 先移除旧模型
            self.monsterNode:removeChild(self.monsterNode.bineDisplay);
        end

        -- 无条件移除太阳花界面
        UIMgr.getCurrentScene():removeFormByName("UISunFlower");

        -- 初始化没有种植的花园
        self.barNode:setVisible(true);
        initEmptyGarden(self);
        return;
    end

    -- 魔藤已生长，创建其外观
    createBine(self);
end

-- 初始化没有种植的花园
function initEmptyGarden(self)
    -- 隐藏技能气泡和血条
    self.bineSkillNode:setVisible(false);
    self.barNode:setVisible(false);

    local class = self.gridData.class;
    local buildingInfo = BuildingBonusM.queryBuildingView(class);

    if not buildingInfo then
        error("获取不到建筑查看配置，元素类型：" .. class);
        return;
    end

    local function onClicked(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            local pos = self.gridData:getPos();

            -- 尝试种植
            local function tryPlant(classId)
                local ret = BineM.canPlant(pos, classId);
                if ret ~= true then
                    if ret == "lack_cost" then
                        -- 消耗不足
                        alert(getLocStr("garden_plant_lack_cost"));
                    end
                    return;
                end
                -- 种植
                DungeonActionM.go("bine_grow", pos, classId);
                return;
            end


            -- 种植魔藤
            local function tryPlantBine()
                tryPlant(PLANT_CLASS_BINE);
            end

            -- 种植太阳花
            local function tryPlantSunFlower()
                tryPlant(PLANT_CLASS_SUN_FLOWER);
            end

            local canPlantBine = BineM.canPlant(pos, PLANT_CLASS_BINE);
            local canPlantSunFlower = BineM.canPlant(pos, PLANT_CLASS_SUN_FLOWER);

            local bineSeedId = BineM.query(PLANT_CLASS_BINE, "seed");
            local sunFlowerSeedId = BineM.query(PLANT_CLASS_SUN_FLOWER, "seed");
            if canPlantBine == true and canPlantSunFlower == true then
                -- 两种都能种植，让玩家自己选
                self:openBuildingView2(tryPlantBine, tryPlantSunFlower,
                    ItemM.query(bineSeedId, "name"),
                    ItemM.query(sunFlowerSeedId, "name"));
                    AudioM.playFx("button_caption");
            elseif canPlantBine == true then
                -- 种植魔藤
                self:openBuildingView(tryPlantBine);
                AudioM.playFx("button_caption");
            elseif canPlantSunFlower == true then
                -- 种植太阳花
                self:openBuildingView(tryPlantSunFlower);
                AudioM.playFx("button_caption");
            else
                alert(getLocStr("garden_plant_lack_cost"));
                AudioM.playFx("button_receive_failed");
            end
        end
    end

    -- 建筑图标
    local iconPath = getLevelItemIconPath("garden");

    self.icon = ccui.ImageView:create(iconPath);
    self.icon:setTouchEnabled(true);
    self.icon:addTouchEventListener(onClicked);
    self.icon:setPositionY(-9);
    self.item:addChild(self.icon);
    self.iconPath = iconPath;

    -- 是否闪光
    if buildingInfo["shinning"] == 1 then
        self.shiningAjustPos = cc.p(70, 100);
        shiningEffect(self.icon, self.shiningAjustPos.x, self.shiningAjustPos.y);
    end
end

-- 创建魔藤
function createBine(self)
    local function onClicked(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            if ME.user.bine.classId == PLANT_CLASS_BINE then
                -- 打开魔藤主界面
                UIMgr.getCurrentScene():removeFormByName("UIBineMain");
                local uiBineMain = UIBineMain.create();
                UIMgr.getCurrentScene():addForm(uiBineMain);
                AudioM.playFx("workshop_itemappear");
            elseif ME.user.bine.classId == PLANT_CLASS_SUN_FLOWER then
                require "game/ui/form/bine/UISunFlower";
                -- 打开太阳花主界面
                UIMgr.getCurrentScene():removeFormByName("UISunFlower");
                local uiForm = UISunFlower.create(self.gridData:getPos());
                UIMgr.getCurrentScene():addForm(uiForm);
                AudioM.playFx("workshop_itemappear");
            end
        end
    end

    -- 花园图标
    local iconPath = getLevelItemIconPath("garden");
    self.icon = ccui.ImageView:create(iconPath);
    self.icon:setTouchEnabled(true);
    self.icon:addTouchEventListener(onClicked);
    self.icon:setPositionY(-9);
    self.item:addChild(self.icon);
    self.iconPath = iconPath;

    if self.monsterNode.bineDisplay then
        -- 先移除旧模型
        self.monsterNode:removeChild(self.monsterNode.bineDisplay);
    end

    -- 显示魔藤信息
    local function showBineInfo()
        -- 创建模藤模型
        local bineDisplay = createBineDisplay(self);
        self.monsterNode.bineDisplay = bineDisplay;
        self.monsterNode:addChild(bineDisplay);
        self.monsterNode:setVisible(true);

        if ME.user.bine.classId == PLANT_CLASS_BINE then
            -- 重绘魔藤技能气泡
            self:redrawBineSkill();

            -- 显示攻击和生命
            self.barNode:setVisible(true);
            self:redrawBineAttackAndHp();

            -- 显示自动攻击轮次倒计时
            self:updateCountDown();
        end
    end
    performWithDelay(self, showBineInfo, 0.1);

    -- 注册技能气泡点击事件
    local dialogBg = findChildByName(self.bineSkillNode, "bg");
    dialogBg:setTouchEnabled(true);
    local function onDialogBgClick(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            if ME.user.bine.classId ~= PLANT_CLASS_BINE then
                return;
            end

            -- 判断魔藤是否死亡
            if ME.user.bine:isDead() then
                alert(getLocStr("bine_is_dead"));
                return;
            end

            -- 判断魔法值是否足够
            if not isBineMpEnouth() then
                alert(getLocStr("no_enough_mp"));
                return;
            end

            -- 音效
            AudioM.playFx("button_click");

            -- 打开魔藤施法界面
            local skillId = BineM.getInitiativeSkill();
            UIMgr.getCurrentScene():removeFormByName("UIBineSelectTarget");
            local uiForm = UIBineSelectTarget.create(skillId);
            UIMgr.getCurrentScene():addForm(uiForm);
        end
    end
    dialogBg:addTouchEventListener(onDialogBgClick);
end

-- 判断魔法值是否足够
function isBineMpEnouth()
    -- 判断魔法值是否足够
    local skillId = BineM.getInitiativeSkill();
    local mp = BineM.calcSkillCost(skillId);
    if ME.user.bine:getMp() < mp then
        return false
    end

    return true;
end

-- 创建魔藤模型
function createBineDisplay(self)
    -- 创建模型
    local bine = ME.user.bine;
    local classId = bine.classId;
    local bineDisplay = BineDisplay.create(classId);

    -- 设置缩放比例
    local scale = BineM.query(classId, "model_scale");
    bineDisplay:setScale(scale);

    -- 设置偏移量
    local offsetX = BineM.query(classId, "offset_x") or 0;
    local offsetY = BineM.query(classId, "offset_y") or 0;

    bineDisplay:setPosition(tonumber(offsetX), tonumber(offsetY));
    return bineDisplay;
end

-- 重绘魔藤的攻击和生命
function redrawBineAttackAndHp(self)
    local bine = ME.user.bine;
    if not bine then
        -- 获取不到魔藤对象
        return;
    end

    -- 如果魔藤死亡了，需要隐藏血条和攻击条
    if bine:isDead() then
        self.barNode:setVisible(false);

        -- 花园图片要灰化处理
        setGrayMode(self.icon, true);
    else
        self.barNode:setVisible(true);

        -- 花园图片高亮
        setGrayMode(self.icon, false);
    end

    local hpLabel = self.hpLabel;
    local attackLabel = self.attackLabel;

    -- 显示血量和攻击
    local hp = bine:getHp();
    hpLabel:setString(tostring(hp));

    local attack = bine:getAttack();
    attackLabel:setString(tostring(attack));

    self:setBarStyle(hpLabel);
    self:setBarStyle(attackLabel);

    -- 处理魔藤属性增加的特效
    handleBineAttribEffect(self);
end

-- 重绘魔藤技能气泡
function redrawBineSkill(self)
    -- 如果魔藤学习了主动技能，则显示气泡
    local skillId = BineM.getInitiativeSkill();
    local bine = ME.user.bine;
    if bine:ownSkill(skillId) and not bine:isDead() then

        local skillIconPath = getSkillIconPath(SkillM.query(skillId, "icon"));
        local skillIconImg = findChildByName(self.bineSkillNode, "icon");
        skillIconImg:loadTexture(skillIconPath);

        if not isBineMpEnouth() then
            -- 魔法值不足
            setGrayTransMode(skillIconImg, true);
        else
            setGrayTransMode(skillIconImg, false);
        end

        -- 播放气泡动画
        if not self.bineSkillNode.isPlaying then
            playBubbleAnima(self.bineSkillNode, false);
            self.bineSkillNode.isPlaying = true;
        end
    else
        self.bineSkillNode:setVisible(false);
    end
end

-- 处理魔藤属性增加的特效
function handleBineAttribEffect(self)
    local parentNode = UIDungeonMgr:getCurLevel():getEffectParent();
    local function delayHandle()
        local bine   = ME.user.bine;
        local attack = bine:getAttack();
        local magic  = bine:getMagic();
        local curHp  = bine:getHp();
        local curMp  = bine:getMp();

        local pos = bine:getPos();
        local binePos = UIDungeonMgr:getCurLevel():getBinePos(pos);

        local addList = {};

        -- 攻击+N效果
        local delay = 0.01;
        local lastAttack = bine.dbase:queryTemp("last_attack");
        if lastAttack ~= nil then
            local addValue =  attack - lastAttack;
            if addValue > 0 then
                table.insert(addList, { "attack", addValue, cc.pAdd(binePos, cc.p(0, 30)) });
            end
        end
        bine.dbase:setTemp("last_attack", attack);

        -- 魔力+N效果
        local lastMagic = bine.dbase:queryTemp("last_magic");
        if lastMagic ~= nil then
            local addValue =  magic - lastMagic;
            if addValue > 0 then
                table.insert(addList, { "magic", addValue, cc.pAdd(binePos, cc.p(0, 30)) });
            end
        end
        bine.dbase:setTemp("last_magic", magic);

        -- 生命值+N效果
        local lastHp = bine.dbase:queryTemp("last_hp");
        if lastHp ~= nil then
            local addValue = curHp - lastHp;
            if addValue > 0 then
                local xOffset = iif(addValue >= 100, -10, 15);
                table.insert(addList, { "max_hp", addValue, cc.pAdd(binePos, cc.p(xOffset, 30)) });
            end
        end
        bine.dbase:setTemp("last_hp", curHp);

        -- 魔法值+N效果
        local lastMp = bine.dbase:queryTemp("last_mp");
        if lastMp ~= nil then
            local addValue =  curMp - lastMp;
            if addValue > 0 then
                local xOffset = iif(addValue >= 100, -10, 15);
                table.insert(addList, { "max_mp", addValue, cc.pAdd(binePos, cc.p(xOffset, 30)) });
            end
        end
        bine.dbase:setTemp("last_mp", curMp);

        -- 播放特效
        local i = 1;
        local bineCol = pos % DUNGEON_WIDTH;
        bineCol = iif(bineCol == 0, DUNGEON_WIDTH, bineCol);
        for _, arr in pairs(addList) do
            local attrib = arr[1];
            local value  = arr[2];
            local offset = arr[3];
            if value > 0 then
                local function callFunc()
                    if bineCol == 1 then
                        -- 魔藤格子在第一列，则特效还要往右偏移一点
                        offset = cc.pAdd(offset, cc.p(25, 0));
                    elseif bineCol == DUNGEON_WIDTH then
                        -- 魔藤在最后一列，则特效还要往左偏移一点
                        local offsetX = -25;
                        if value >= 10 then
                           offsetX = -40;
                        elseif value >= 100 then
                           offsetX = -50;
                        end
                        offset = cc.pAdd(offset, cc.p(offsetX, 0));
                    end

                    playAttribUpEffect(parentNode, value, offset, attrib);
                end

                performWithDelay(self, callFunc, 0.01 + 0.8* (i - 1));
                i = i + 1;
            end
        end
    end

    performWithDelay(self, delayHandle, 0.01);
end

-- 种植魔藤的事件
function onPlantBine(self)
    -- 提示种植成功
    alert(getLocStr("garden_plant_succ"));
    AudioM.playFx("market_buy_success");

    -- 重新初始化格子
    initGarden(self);
end
